home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 3 code / ISO 9660 & High Sierra / iso9660 ƒ / BuildISO.c next >
Encoding:
C/C++ Source or Header  |  1990-06-05  |  18.6 KB  |  747 lines  |  [TEXT/KAHL]

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include <FileMgr.h>
  5. #include <pascal.h>
  6. #include <OSUtil.h>
  7.  
  8. /************************************************************************
  9.  *
  10.  *    © Copyright 1988, 1990 Apple Computer, Inc.  All rights reserved.
  11.  *
  12.  *  Program:        BuildISO
  13.  *
  14.  *  Purpose:        build an ISO 9660 floppy
  15.  *
  16.  *  Description:    Try to build a ISO 9660 floppy disc, interactively.
  17.  *                    Currently only builds the Primary Volume Descriptor.
  18.  *
  19.  *  Revision History:
  20.  *    1 July 88    Original Version for the Macintosh by Brian Bechtel,
  21.  *                Apple Computer, Inc.
  22.  *    April 90    Modified for d e v e l o p and Think C 4.0
  23.  *
  24.  ************************************************************************/
  25.  
  26. #include "HighSierra.h"
  27. #include "BuildISO.h"
  28.  
  29. #define    FLOPPY_SIZE    0x186        /* size in 2k blocks of a 800k floppy */
  30.  
  31. Str255            nullStr = "\p";
  32. Str255            rootName = "\p\000";
  33. Str255            parentName = "\p\001";
  34.  
  35. /************************************************************************
  36.  *
  37.  *  Function:        CreatePVD
  38.  *
  39.  *  Purpose:        create the contents of the Primary Volume Descriptor.
  40.  *
  41.  *  Returns:        void
  42.  *
  43.  *  Side Effects:    adds to the output file.
  44.  *
  45.  *  Description:    go through all the primary volume descriptor, showing
  46.  *                    each field in all it's glory.  We don't bother showing
  47.  *                    the extra blanks at the end of each string field.
  48.  *
  49.  *
  50.  ************************************************************************/
  51.  
  52. OSErr
  53. CreatePVD(referenceNumber)
  54. short    referenceNumber;
  55. {
  56.     PVD        p;
  57.     short    i;
  58.     OSErr    result;
  59.     long    offset;
  60.     char    volID[33];
  61.     Boolean    goOn;
  62.     char    errorString[255];
  63.     
  64.     ClearOut((char *)&p, sizeof(p));
  65.     p.VDType = 1;
  66.     p.VSStdId[0] = 'C';
  67.     p.VSStdId[1] = 'D';
  68.     p.VSStdId[2] = '0';
  69.     p.VSStdId[3] = '0';
  70.     p.VSStdId[4] = '1';
  71.     p.VSStdVersion = 1;
  72.     CharCopy(p.systemIdentifier, "Apple Computer, Inc., Type:0001", sizeof(p.systemIdentifier));
  73.  
  74.     goOn = AskForString("\pWhat do you want to call this volume? (32 characters or less)", volID);
  75.     if (goOn == false)
  76.         return -1;
  77.  
  78.     NormalizeVolumeName(volID);
  79.     CharCopy(p.volumeIdentifier, volID, sizeof(p.volumeIdentifier));
  80.  
  81.  
  82.     p.lsbVolumeSpaceSize = NormalizeLong((long)FLOPPY_SIZE);
  83.     p.msbVolumeSpaceSize = (long)FLOPPY_SIZE;
  84.     p.lsbVolumeSetSize = NormalizeWord(FLOPPY_SIZE);
  85.     p.msbVolumeSetSize = FLOPPY_SIZE;
  86.     p.lsbVolumeSetSequenceNumber = NormalizeWord(1);
  87.     p.msbVolumeSetSequenceNumber = 1;
  88.     
  89.     p.lsbLogicalBlockSize = NormalizeWord(CDBLKSIZE);
  90.     p.msbLogicalBlockSize = CDBLKSIZE;
  91.                 
  92.  
  93.     p.lsbPathTableSize = NormalizeLong(PATHTBLSIZE);
  94.     p.msbPathTableSize = PATHTBLSIZE;
  95.     p.lsbPathTable1 = NormalizeLong(LSBPATH);
  96.     p.msbPathTable1 = MSBPATH;
  97.     
  98.     p.lsbPathTable2 = 0L;
  99.     p.msbPathTable2 = 0L;
  100.     
  101.     /* Exercise for reader: get the time via GetTime() and convert
  102.     ** to string of the format shown below for these strange dates.
  103.     ** Use that date and time to fill the various volume date fields.
  104.     ** The date shown is my daughter's birth date and time...
  105.     */
  106.     CharCopy(p.volumeCreation, "19870914060100000", sizeof(p.volumeCreation));
  107.     CharCopy(p.volumeModification, "19870914060100000", sizeof(p.volumeModification));
  108.     CharCopy(p.volumeExpiration, "00000000000000000", sizeof(p.volumeExpiration));
  109.     CharCopy(p.volumeEffective, "19870914060100000", sizeof(p.volumeEffective));
  110.  
  111.     p.FileStructureStandardVersion = 1;
  112.     
  113.     SpaceOut(p.volumeSetIdentifier, sizeof(p.volumeSetIdentifier));
  114.     SpaceOut(p.publisherIdentifier, sizeof(p.publisherIdentifier));
  115.     SpaceOut(p.dataPreparerIdentifier, sizeof(p.dataPreparerIdentifier));
  116.     SpaceOut(p.applicationIdentifier, sizeof(p.applicationIdentifier));
  117.     SpaceOut(p.copyrightFileIdentifier, sizeof(p.copyrightFileIdentifier));
  118.     SpaceOut(p.abstractFileIdentifier, sizeof(p.abstractFileIdentifier));
  119.     SpaceOut(p.bibliographicFileIdentifier, sizeof(p.bibliographicFileIdentifier));
  120.  
  121.     CreateDirRcd((DirRcd *)&p.rootDirectoryRecord, rootName, 
  122.         DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
  123.     
  124.     p.Reserved1 = 0;
  125.     ClearOut(p.Reserved2, sizeof(p.Reserved2));
  126.     ClearOut(p.Reserved3, sizeof(p.Reserved3));
  127.     p.Reserved4 = 0;
  128.  
  129. #ifdef VERBOSE    /* if I want to verify what I've done */
  130.     DumpPVD(&p);
  131. #endif
  132.     offset = (long) HSVOLSTART * (long) CDBLKSIZE;
  133.     result = isoWrite(referenceNumber, (Ptr)&p, (long) sizeof(p), (long)offset);
  134.     if (result != noErr)
  135.         ErrorMsg("CreatePVD: isoWrite() returned %d", result);
  136.     else
  137.         ErrorMsg("volume descriptors successfully created.");
  138.     return result;
  139. }
  140.  
  141.  
  142. /************************************************************************
  143.  *
  144.  *  Function:        CreateVDT
  145.  *
  146.  *  Purpose:        create the contents of the Volume Descriptor Terminator
  147.  *
  148.  *  Returns:        void
  149.  *
  150.  *  Side Effects:    adds to the output file.
  151.  *
  152.  *  Description:    Build a simple VDT, fill it in, and write it out to
  153.  *                    a famous place.
  154.  *
  155.  *
  156.  ************************************************************************/
  157.  
  158. OSErr
  159. CreateVDT(referenceNumber)
  160. short    referenceNumber;
  161. {
  162.     PVD        p;
  163.     short    i;
  164.     OSErr    result;
  165.     long    offset;
  166.     char    volID[33];
  167.     
  168.     ClearOut((char *)&p, sizeof(p));
  169.     p.VDType = 255;
  170.     p.VSStdId[0] = 'C';
  171.     p.VSStdId[1] = 'D';
  172.     p.VSStdId[2] = '0';
  173.     p.VSStdId[3] = '0';
  174.     p.VSStdId[4] = '1';
  175.     p.VSStdVersion = 1;
  176.     offset = (long) HSTERMSTART * (long) CDBLKSIZE;
  177.     result = isoWrite(referenceNumber, (Ptr)&p, (long) sizeof(p), (long)offset);
  178.     if (result != noErr)
  179.         ErrorMsg("CreateVDT: isoWrite() returned %d", result);
  180.     return result;
  181. }
  182.  
  183.  
  184.  
  185.  
  186. /************************************************************************
  187.  *
  188.  *  Function:        CreatePathTable
  189.  *
  190.  *  Purpose:        create path tables
  191.  *
  192.  *  Returns:        nothing
  193.  *
  194.  *  Side Effects:    writes lsb path table and msb path table
  195.  *
  196.  *  Description:    We'll assume just the root.  Dump out the path
  197.  *                    path table in both formats.  We'll put the
  198.  *                    path table in famous spots.
  199.  *
  200.  ************************************************************************/
  201. OSErr
  202. CreatePathTable(referenceNumber)
  203. short    referenceNumber;
  204. {
  205.     char    buffer[CDBLKSIZE];
  206.     PathTableRecordPtr    d;
  207.     long    offset;
  208.     OSErr    result;
  209.     
  210.     ClearOut(buffer, sizeof(buffer));
  211.     d = (PathTableRecordPtr) &buffer[0];
  212.     
  213.     d->len_di = 1;
  214.     d->XARlength = 0;
  215.     d->dirLocation = NormalizeLong(DIRECTORY);
  216.     d->parentDN = 0;
  217.     
  218.     offset = LSBPATH * (long) CDBLKSIZE;
  219.     result = isoWrite(referenceNumber, buffer, (long) CDBLKSIZE, offset);
  220.     if (result != noErr)
  221.         ErrorMsg("CreatePathTable: isoWrite() returned %d", result);
  222.     
  223.     d->len_di = 1;
  224.     d->dirLocation = DIRECTORY;
  225.     d->parentDN = 0;
  226.     
  227.     offset = MSBPATH * (long) CDBLKSIZE;
  228.     result = isoWrite(referenceNumber, buffer, (long) CDBLKSIZE, offset);
  229.     if (result != noErr)
  230.         ErrorMsg("CreatePathTable: isoWrite() returned %d", result);
  231.     return result;
  232. }
  233.  
  234.  
  235. /************************************************************************
  236.  *
  237.  *  Function:    CreateDirRcd
  238.  *
  239.  *  Purpose:    Create a directory record for a file
  240.  *
  241.  *  Returns:    none
  242.  *
  243.  *  Side Effects:    fills *d with directory information.  We assume
  244.  *                    caller has allocated space for d.
  245.  *
  246.  *  Description:
  247.  *
  248.  ************************************************************************/
  249. void
  250. CreateDirRcd(d, name, start, length, flags, fType, fCreator, finderFlags)
  251. DirRcd    *d;
  252. StringPtr name;
  253. long    start;
  254. long    length;
  255. short    flags;
  256. OSType    fType;
  257. OSType    fCreator;
  258. short    finderFlags;
  259. {
  260.     Ptr        dPtr;
  261.     short    i;
  262.     DateTimeRec    today;
  263.  
  264.     d->XARlength = 0;
  265.     d->lsbStart = NormalizeLong(start);
  266.     d->msbStart = start;
  267.     d->lsbDataLength = NormalizeLong(length);
  268.     d->msbDataLength = length;
  269.     d->fileFlags = flags;
  270.     if (finderFlags & fInvisible)
  271.         d->fileFlags |= existenceBit;
  272.     GetTime(&today);
  273.     d->year = today.year-1900;
  274.     d->month = today.month;
  275.     d->day = today.day;
  276.     d->hour = today.hour;
  277.     d->minute = today.minute;
  278.     d->second = today.second;
  279.     d->gmtOffset = 0;
  280.     d->interleaveSize = 0;
  281.     d->interleaveSkip = 0;
  282.     d->lsbVolSetSeqNum = NormalizeWord(1);
  283.     d->msbVolSetSeqNum = 1;
  284.     
  285.     d->len_fi = CreateISOName((char *)d->fi, name);
  286.  
  287.     d->len_dr = 32 + d->len_fi;
  288.     
  289.     AddAppleExtensions(d, fType, fCreator, finderFlags);
  290.     
  291.     if (d->len_dr & 1)    /* odd dirRcds need pad byte */
  292.     {
  293.         dPtr = (char *)d;
  294.         dPtr[d->len_dr] = '\000';
  295.         d->len_dr++;
  296.     }
  297. }
  298.  
  299.  
  300. /************************************************************************
  301.  *
  302.  *  Function:        AddOldAppleExtensions
  303.  *
  304.  *  Purpose:        optionally add apple extensions to ISO 9660
  305.  *
  306.  *  Returns:        void
  307.  *
  308.  *  Side Effects:    directory record may get extended.  Must have enough
  309.  *                    room in area pointed to by dirRcd for this to happen.
  310.  *
  311.  *  Description:    Check the fType.  If it's non-zero, add the information
  312.  *                    necessary for the Apple Extensions to ISO 9660.  Note
  313.  *                    that we can't just assign fType and fCreator, since
  314.  *                    longs are aligned within structures.
  315.  *
  316.  *                    This procedure adds the old, "BA" Apple extensions.
  317.  *
  318.  ************************************************************************/
  319. void
  320. AddOldAppleExtensions(dirRcd, fType, fCreator, flags)
  321. DirRcd    *dirRcd;
  322. OSType    fType;
  323. OSType    fCreator;
  324. short    flags;
  325. {
  326.     OldAppleExtension    apple;
  327.     short            i;
  328.     short            j;
  329.     short            limit;
  330.     char            *aPtr;
  331.     Ptr                fPtr;
  332.     
  333.     if (fType != 0L)
  334.     {
  335.         apple.macFlag[0] = 'B';
  336.         apple.macFlag[1] = 'A';
  337.         apple.systemUseID = 06;
  338.         fPtr = (char *)&fType;
  339.         
  340.         for (i = 0; i < 4; i++)
  341.             apple.fileType[i] = fPtr[i];
  342.         fPtr = (char *)&fCreator;
  343.         
  344.         for (i = 0; i < 4; i++)
  345.             apple.fileCreator[i] = fPtr[i];
  346.         
  347.         apple.finderFlags[0] = (flags >> 8) & 0xFF;
  348.         apple.finderFlags[1] = flags & 0xFF;
  349.         
  350.         limit = sizeof(apple);
  351.         
  352.         aPtr = (char *)&apple;
  353.  
  354.         j = dirRcd->len_fi;
  355.         
  356.         if (j & 1)
  357.         {
  358.             dirRcd->fi[j] = 0;
  359.             j++;    /* there is a pad byte after odd length file names */
  360.         }
  361.         
  362.         for (i = 0; i <= limit; i++)
  363.             dirRcd->fi[i + j] = aPtr[i];
  364.         
  365.         dirRcd->len_dr += limit;
  366.     }
  367. }    
  368.  
  369.  
  370. /************************************************************************
  371.  *
  372.  *  Function:        AddAppleExtensions
  373.  *
  374.  *  Purpose:        optionally add apple extensions to ISO 9660
  375.  *
  376.  *  Returns:        void
  377.  *
  378.  *  Side Effects:    directory record may get extended.  Must have enough
  379.  *                    room in area pointed to by dirRcd for this to happen.
  380.  *
  381.  *  Description:    Check the fType.  If it's non-zero, add the information
  382.  *                    necessary for the Apple Extensions to ISO 9660.  Note
  383.  *                    that we can't just assign fType and fCreator, since
  384.  *                    longs are aligned within structures.
  385.  *
  386.  ************************************************************************/
  387. void
  388. AddAppleExtensions(dirRcd, fType, fCreator, flags)
  389. DirRcd    *dirRcd;
  390. OSType    fType;
  391. OSType    fCreator;
  392. short    flags;
  393. {
  394.     AppleExtension    apple;
  395.     short            i;
  396.     short            j;
  397.     short            limit;
  398.     char            *aPtr;
  399.     Ptr                fPtr;
  400.     
  401.     if (fType != 0L)
  402.     {
  403.         apple.signature[0] = 'A';
  404.         apple.signature[1] = 'A';
  405.         apple.extensionLength = 0x0E;
  406.         apple.systemUseID = 02;
  407.         fPtr = (char *)&fType;
  408.         
  409.         for (i = 0; i < 4; i++)
  410.             apple.fileType[i] = fPtr[i];
  411.         fPtr = (char *)&fCreator;
  412.         
  413.         for (i = 0; i < 4; i++)
  414.             apple.fileCreator[i] = fPtr[i];
  415.         
  416.         apple.finderFlags[0] = (flags >> 8) & 0xFF;
  417.         apple.finderFlags[1] = flags & 0xFF;
  418.         
  419.         limit = sizeof(apple);
  420.         
  421.         aPtr = (char *)&apple;
  422.  
  423.         j = dirRcd->len_fi;
  424.         
  425.         if (j & 1)
  426.         {
  427.             dirRcd->fi[j] = 0;
  428.             j++;    /* there is a pad byte after odd length file names */
  429.         }
  430.         
  431.         for (i = 0; i <= limit; i++)
  432.             dirRcd->fi[i + j] = aPtr[i];
  433.         
  434.         dirRcd->len_dr += limit;
  435.     }
  436. }    
  437.  
  438.  
  439. /************************************************************************
  440.  *
  441.  *  Function:        CopyDirRcdToBuffer
  442.  *
  443.  *  Purpose:        copy directory record to buffer
  444.  *
  445.  *  Returns:        nothing
  446.  *
  447.  *  Side Effects:    buffer is filled a little bit more
  448.  *
  449.  *  Description:    copy a directory record to the buffer.
  450.  *
  451.  ************************************************************************/
  452. void
  453. CopyDirRcdToBuffer(d, b)
  454. DirRcd    *d;
  455. char    *b;
  456. {
  457.     char    *dPrime;
  458.     short    i;
  459.     
  460.     dPrime = (char *)d;
  461.     for (i = 0; i < d->len_dr; i++)
  462.         *b++ = *dPrime++;
  463. }
  464.  
  465. /************************************************************************
  466.  *
  467.  *  Function:        CopyRsrcFork
  468.  *
  469.  *  Purpose:        copy the resource fork of a file
  470.  *
  471.  *  Returns:        OSErr
  472.  *                        mostly noErr, but could be
  473.  *                        ioErr and the like if isoWrite complains.
  474.  *
  475.  *  Side Effects:    floppy gets new data written on it.
  476.  *
  477.  *  Description:    we have a starting location, "start", and a length.
  478.  *                    Allocate an appropriate buffer and read from the file
  479.  *                    specified by "name" and "vRefNum".  Write that information
  480.  *                    out to the floppy using our isoWrite call.
  481.  *
  482.  ************************************************************************/
  483. OSErr
  484. CopyRsrcFork(referenceNumber, name, vRefNum, start, length)
  485. short        referenceNumber;        /* reference number for volume we're writing to. */
  486. StringPtr    name;        /* name of file, from HFSFile() */
  487. short        vRefNum;    /* vRefNum of file, from HFSFile() */
  488. long        start;        /* where to start writing to on floppy. */
  489. long        length;        /* how much to write */
  490. {
  491.     Ptr    rsrcBuf;
  492.     ParamBlockRec    pb;
  493.     Boolean        goOn;
  494.     OSErr        result;
  495.     long        physicalLength;
  496.     short        myRefNum;
  497.     
  498.     ClearOut((Ptr)&pb, sizeof(pb));
  499.     goOn = true;
  500.     physicalLength = ROUND_UP(length);
  501.     
  502.     rsrcBuf = NewPtrClear(physicalLength);
  503.     if (rsrcBuf == NULL)
  504.     {
  505.         ErrorMsg("Can't allocate %ld bytes for CopyRsrcFork()", length);
  506.         return mFulErr;    /* nothing to clean up */
  507.     }
  508.  
  509.     pb.ioParam.ioCompletion = NULL;
  510.     pb.ioParam.ioNamePtr = name;
  511.     pb.ioParam.ioVRefNum = vRefNum;
  512.     pb.ioParam.ioVersNum = 0;
  513.     pb.ioParam.ioPermssn = fsCurPerm;
  514.     pb.ioParam.ioMisc = NULL;
  515.     result = PBOpenRF(&pb, false);
  516.     if (result != noErr)
  517.     {
  518.         ErrorMsg("CopyRsrcFork: PBOpenRF returned %d", result);
  519.         ErrorMsg("vRefNum %d, name %s", vRefNum, PtoCstr((char *)name));
  520.         CtoPstr((char *)name);
  521.         goOn = false;
  522.     }
  523.     
  524.     if (goOn)
  525.     {
  526.         myRefNum = pb.ioParam.ioRefNum;
  527.         result = FSRead(myRefNum, &length, rsrcBuf);
  528.         if (result != noErr)
  529.         {
  530.             ErrorMsg("CopyRsrcFork: FSRead returned %d", result);
  531.             goOn = false;
  532.         }
  533.     }
  534.     
  535.     if (goOn)
  536.     {
  537.         result = isoWrite(referenceNumber, rsrcBuf, physicalLength, start);
  538.  
  539.         if (result != noErr)
  540.         {
  541.             ErrorMsg("CopyRsrcFork: isoWrite returned %d", result);
  542.             goOn = false;
  543.         }
  544.     }
  545.         
  546.     PBClose(&pb, false);
  547.     DisposPtr(rsrcBuf);
  548.     return result;
  549. }
  550.  
  551.  
  552.  
  553. /************************************************************************
  554.  *
  555.  *  Function:        CopyDataFork
  556.  *
  557.  *  Purpose:        copy the resource fork of a file
  558.  *
  559.  *  Returns:        OSErr
  560.  *                        mostly noErr, but could be
  561.  *                        ioErr and the like if isoWrite complains.
  562.  *
  563.  *  Side Effects:    floppy gets new data written on it.
  564.  *
  565.  *  Description:    we have a starting location, "start", and a length.
  566.  *                    Allocate an appropriate buffer and read from the file
  567.  *                    specified by "name" and "vRefNum".  Write that information
  568.  *                    out to the floppy using our isoWrite call.
  569.  *
  570.  ************************************************************************/
  571. OSErr
  572. CopyDataFork(referenceNumber, name, vRefNum, start, length)
  573. short        referenceNumber;        /* reference number for volume we're writing to. */
  574. StringPtr    name;        /* name of file, from HFSFile() */
  575. short        vRefNum;    /* vRefNum of file, from HFSFile() */
  576. long        start;        /* where to start writing to on floppy. */
  577. long        length;        /* how much to write */
  578. {
  579.     Ptr    dataBuf;
  580.     ParamBlockRec    pb;
  581.     Boolean        goOn;
  582.     OSErr        result;
  583.     long        physicalLength;
  584.     short        myRefNum;
  585.     
  586.     ClearOut((Ptr)&pb, sizeof(pb));
  587.     goOn = true;
  588.     physicalLength = ROUND_UP(length);
  589.     
  590.     dataBuf = NewPtrClear(physicalLength);
  591.     if (dataBuf == NULL)
  592.     {
  593.         ErrorMsg("Can't allocate %ld bytes for CopyDataFork()", length);
  594.         return mFulErr;    /* nothing to clean up */
  595.     }
  596.     
  597.     pb.ioParam.ioCompletion = NULL;
  598.     pb.ioParam.ioNamePtr = name;
  599.     pb.ioParam.ioVRefNum = vRefNum;
  600.     pb.ioParam.ioVersNum = 0;
  601.     pb.ioParam.ioPermssn = fsCurPerm;
  602.     pb.ioParam.ioMisc = NULL;
  603.     result = PBOpen(&pb, false);
  604.     if (result != noErr)
  605.     {
  606.         ErrorMsg("CopyDataFork: PBOpen returned %d", result);
  607.         ErrorMsg("vRefNum %d, name %s", vRefNum, PtoCstr((char *)name));
  608.         CtoPstr((char *)name);
  609.         goOn = false;
  610.     }
  611.     
  612.     if (goOn)
  613.     {
  614.         myRefNum = pb.ioParam.ioRefNum;
  615.         result = FSRead(myRefNum, &length, dataBuf);
  616.         if (result != noErr)
  617.         {
  618.             ErrorMsg("CopyDataFork: FSRead returned %d", result);
  619.             goOn = false;
  620.         }
  621.     }
  622.     
  623.     if (goOn)
  624.     {
  625.         result = isoWrite(referenceNumber, dataBuf, physicalLength, start);
  626.  
  627.         if (result != noErr)
  628.         {
  629.             ErrorMsg("CopyDataFork: isoWrite returned %d", result);
  630.             goOn = false;
  631.         }
  632.     }
  633.     
  634.     PBClose(&pb, false);
  635.     DisposPtr(dataBuf);
  636.     return result;
  637. }
  638.  
  639. /************************************************************************
  640.  *
  641.  *  Function:        CreateFiles
  642.  *
  643.  *  Purpose:        create files in the root of a ISO floppy.
  644.  *    
  645.  *  Returns:        nothing
  646.  *
  647.  *  Side Effects:    floppy gets new data in famous root area
  648.  *
  649.  *  Description:    For each file, find the size of the two forks.
  650.  *                    Copy the resource fork first, then the data fork
  651.  *                    (associated files come before data files in ISO)
  652.  *
  653.  ************************************************************************/
  654. void
  655. CreateFiles(referenceNumber)
  656. short    referenceNumber;
  657. {
  658.     StringPtr    name;
  659.     short    vRefNum;
  660.     DirRcd    dirRcd;
  661.     long    start;        /* where we start putting data on the CD */
  662.     long    rsrcLength;
  663.     long    dataLength;
  664.     char    *b;
  665.     OSErr    result;
  666.     OSType    fType;
  667.     OSType    fCreator;
  668.     short    flags;
  669.     short    ISOFlags;
  670.     char    buffer[CDBLKSIZE];
  671.     
  672.     
  673.     ClearOut(buffer, sizeof(buffer));
  674.     b = &buffer[0];
  675.     name = (StringPtr)NewPtr(255);
  676.     if (name == NULL)
  677.     {
  678.         ErrorMsg("Can't allocate 255 bytes for a string.");
  679.         return;
  680.     }
  681.  
  682.     CreateDirRcd(&dirRcd, rootName, DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
  683.     CopyDirRcdToBuffer(&dirRcd, b);
  684.     b += dirRcd.len_dr;
  685.  
  686.     CreateDirRcd(&dirRcd, parentName, DIRECTORY, CDBLKSIZE, (short) directoryBit, 0L, 0L, 0);
  687.     CopyDirRcdToBuffer(&dirRcd, b);
  688.     b += dirRcd.len_dr;
  689.  
  690.     start = DATASTART * CDBLKSIZE;
  691.  
  692.     /* Keep asking for names, even if errors occur.  Most errors will be because
  693.      * The user tried to copy too big of a file to the floppy. 
  694.      */
  695.     while (HFSFile(name, &vRefNum) == true)
  696.     {
  697.         result = GetFileInfo(name, vRefNum, &rsrcLength, &dataLength, &fType, &fCreator, &flags);
  698.         if (result != noErr)
  699.             ErrorMsg("Can't get file information for %s", name);
  700.         else
  701.         {
  702.             ISOFlags = (flags & fInvisible) ? existenceBit : 0;
  703.     
  704.             if (rsrcLength != 0L)
  705.             {
  706.                 CreateDirRcd(&dirRcd, name, start/CDBLKSIZE, rsrcLength, ISOFlags | associatedBit,
  707.                     fType, fCreator, flags);
  708.     
  709.                 result = CopyRsrcFork(referenceNumber, name, vRefNum, start, rsrcLength);
  710.                 if (result == noErr)
  711.                 {
  712.                     CopyDirRcdToBuffer(&dirRcd, b);
  713.                     b += dirRcd.len_dr;
  714.                     start = ROUND_UP(start+rsrcLength);
  715.                 }
  716.                 else
  717.                     ErrorMsg("Failed to copy resource fork.");
  718.         
  719.             }
  720.     
  721.             if (result == noErr)
  722.             {
  723.                 CreateDirRcd(&dirRcd, name, start/CDBLKSIZE, dataLength, ISOFlags, 
  724.                     fType, fCreator, flags);
  725.         
  726.                 result = CopyDataFork(referenceNumber, name, vRefNum, start, dataLength);
  727.                 if (result == noErr)
  728.                 {
  729.                     CopyDirRcdToBuffer(&dirRcd, b);
  730.                     b += dirRcd.len_dr;
  731.                     start = ROUND_UP(start+dataLength);
  732.                 }
  733.                 else
  734.                     ErrorMsg("Failed to copy data fork.");
  735.         
  736.                 ClearOut((Ptr)name, 255);
  737.             }
  738.         }
  739.     }
  740.  
  741.     result = isoWrite(referenceNumber, (Ptr)buffer, (long)sizeof(buffer), (long) (DIRECTORY*CDBLKSIZE));
  742.     if (result != noErr)
  743.         ErrorMsg("CreateDataFiles: isoWrite of directory records returned %d", result);
  744.     DisposPtr(name);
  745. }
  746.  
  747.